package com.yunxin.core.application.assembler;

import com.yunxin.core.application.command.product.*;
import com.yunxin.core.application.dto.product.*;
import com.yunxin.core.domain.model.product.*;
import com.yunxin.core.infra.persistence.entity.product.*;
import com.yunxin.core.infra.persistence.entity.product.query.condition.ProductPageCondition;
import com.yunxin.core.infra.persistence.entity.product.query.result.*;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;

/**
 * @author zero°
 * @since 2023-05-31
 */
@Mapper(componentModel = "spring")
public interface ProductAssembler {

    /**
     * entity 转 dto
     * @param entity entity
     * @return ProductAdvanceChargeRecordPageDTO
     */
    @Mapping(target = "advanceChargeDate", expression = "java(com.yunxin.core.utils.infra.utils.DateFormatUtils.X.getDateStr(entity.getAdvanceChargeDate()))")
    @Mapping(target = "settlementTypeStr", expression = "java(com.yunxin.common.base.IBaseEnum.getLabelByValue(entity.getSettlementType(), com.yunxin.core.infra.common.product.enums.ProductSettlementTypeEnum.class))")
    @Mapping(target = "settlementAmount", expression = "java(entity.getSettlementUnitPrice().multiply(new java.math.BigDecimal(entity.getSettlementNumber())))")
    ProductAdvanceChargeRecordPageDTO toProductAdvanceChargeRecordPageDTO(ProductAdvanceChargeRecordDO entity);


    /**
     * entity 转 dto
     * @param entity entity
     * @return ProductAdvanceChargeRecordDetailDTO
     */
    @Mapping(target = "advanceChargeDate", expression = "java(com.yunxin.core.utils.infra.utils.DateFormatUtils.X.getDateStr(entity.getAdvanceChargeDate()))")
    ProductAdvanceChargeRecordDetailDTO toProductAdvanceChargeRecordDetailDTO(ProductAdvanceChargeRecordDO entity);

    /**
     * result 转 dto
     *
     * @param result result
     * @return ProductPageDTO
     */
    @Mapping(target = "productTypeStr", expression = "java(com.yunxin.common.base.IBaseEnum.getLabelByValue(result.getProductType(), com.yunxin.core.infra.common.product.enums.ProductTypeEnum.class))")
    @Mapping(target = "productStatusStr", expression = "java(com.yunxin.common.base.IBaseEnum.getLabelByValue(result.getProductStatus(), com.yunxin.core.infra.common.product.enums.ProductStatusEnum.class))")
    @Mapping(target = "chargedWayStr", expression = "java(com.yunxin.common.base.IBaseEnum.getLabelByValue(result.getChargedWay(), com.yunxin.core.utils.infra.common.enums.ChargedWayTypeEnum.class))")
    ProductPageDTO toProductPageDTO(ProductPageResult result);

    /**
     * entity 转 dto
     *
     * @param entity entity
     * @return ProductChargedListDTO
     */
    @Mapping(target = "chargedWayStr", expression = "java(com.yunxin.common.base.IBaseEnum.getLabelByValue(entity.getChargedWay(), com.yunxin.core.utils.infra.common.enums.ChargedWayTypeEnum.class))")
    ProductChargedListDTO toProductChargedListDTO(ProductUnitPriceConfigVersionDO entity);

    /**
     * result 转 dto
     *
     * @param result result
     * @return ProductChargedListDTO
     */
    @Mapping(target = "chargedWayStr", expression = "java(com.yunxin.common.base.IBaseEnum.getLabelByValue(result.getChargedWay(), com.yunxin.core.utils.infra.common.enums.ChargedWayTypeEnum.class))")
    ProductChargedInfoDTO toProductChargedInfoDTO(ProductChargedInfoResult result);

    /**
     * result 转 dto
     *
     * @param result result
     * @return ProductInfoDTO
     */
    @Mapping(target = "equityDescription", expression = "java(com.yunxin.common.utils.JacksonUtils.X.parse(result.getEquityDescription(), new com.fasterxml.jackson.core.type.TypeReference<java.util.List<com.yunxin.core.application.dto.product.ProductInfoDTO.EquityDescription>>() {}))")
    @Mapping(target = "customerServiceConfig", expression = "java(com.yunxin.common.utils.JacksonUtils.X.parse(result.getCustomerServiceConfig(),com.yunxin.core.application.dto.product.ProductInfoDTO.CustomerServiceConfig.class))")
    @Mapping(target = "protocolConfig", expression = "java(com.yunxin.common.utils.JacksonUtils.X.parse(result.getProtocolConfig(), new com.fasterxml.jackson.core.type.TypeReference<java.util.List<com.yunxin.core.application.dto.product.ProductInfoDTO.ProtocolConfig>>() {}))")
    ProductInfoDTO toProductInfoDTO(ProductInfoResult result);

    /**
     * result 转 dto
     *
     * @param result result
     * @return ProductPromotionInfoDTO
     */
    @Mapping(target = "equityDescription", expression = "java(com.yunxin.common.utils.JacksonUtils.X.parse(result.getEquityDescription(), new com.fasterxml.jackson.core.type.TypeReference<java.util.List<com.yunxin.core.application.dto.product.ProductPromotionInfoDTO.EquityDescription>>() {}))")
    @Mapping(target = "borrowableAmount", expression = "java(com.yunxin.common.utils.JacksonUtils.X.parse(result.getBorrowableAmount(),com.yunxin.core.application.dto.product.ProductPromotionInfoDTO.BorrowableAmount.class))")
    @Mapping(target = "loanCycle", expression = "java(com.yunxin.common.utils.JacksonUtils.X.parse(result.getLoanCycle(),com.yunxin.core.application.dto.product.ProductPromotionInfoDTO.LoanCycle.class))")
    @Mapping(target = "referenceRate", expression = "java(com.yunxin.common.utils.JacksonUtils.X.parse(result.getReferenceRate(),com.yunxin.core.application.dto.product.ProductPromotionInfoDTO.ReferenceRate.class))")
    @Mapping(target = "commission", expression = "java(com.yunxin.common.utils.JacksonUtils.X.parse(result.getCommission(),com.yunxin.core.application.dto.product.ProductPromotionInfoDTO.Commission.class))")
    @Mapping(target = "customerServiceConfig", expression = "java(com.yunxin.common.utils.JacksonUtils.X.parse(result.getCustomerServiceConfig(),com.yunxin.core.application.dto.product.ProductPromotionInfoDTO.CustomerServiceConfig.class))")
    @Mapping(target = "protocolConfig", expression = "java(com.yunxin.common.utils.JacksonUtils.X.parse(result.getProtocolConfig(), new com.fasterxml.jackson.core.type.TypeReference<java.util.List<com.yunxin.core.application.dto.product.ProductPromotionInfoDTO.ProtocolConfig>>() {}))")
    ProductPromotionInfoDTO toProductPromotionInfoDTO(ProductPromotionInfoResult result);

    /**
     * entity 转 dto
     *
     * @param entity entity
     * @return ProductThrowInConfigDTO
     */
    ProductThrowInConfigDTO toProductThrowInConfigDTO(ProductThrowInConfigDOWithBLOBs entity);

    /**
     * entity 转 dto
     *
     * @param entity entity
     * @return ProductCustomConfigDTO
     */
    @Mapping(target = "beOverdueList", expression = "java(com.yunxin.core.utils.infra.utils.ConvertUtils.X.toIntegerList(entity.getBeOverdue(), com.yunxin.core.utils.infra.common.constant.CommonConstants.COMMA))")
    @Mapping(target = "sexList", expression = "java(com.yunxin.core.utils.infra.utils.ConvertUtils.X.toIntegerList(entity.getSexes(), com.yunxin.core.utils.infra.common.constant.CommonConstants.COMMA))")
    @Mapping(target = "sesameSeedQuotaList", expression = "java(com.yunxin.core.utils.infra.utils.ConvertUtils.X.toIntegerList(entity.getSesameSeedQuotas(), com.yunxin.core.utils.infra.common.constant.CommonConstants.COMMA))")
    @Mapping(target = "antCreditPayQuotaList", expression = "java(com.yunxin.core.utils.infra.utils.ConvertUtils.X.toIntegerList(entity.getAntCreditPayQuotas(), com.yunxin.core.utils.infra.common.constant.CommonConstants.COMMA))")
    @Mapping(target = "jdBtQuotaList", expression = "java(com.yunxin.core.utils.infra.utils.ConvertUtils.X.toIntegerList(entity.getJdBtQuotas(), com.yunxin.core.utils.infra.common.constant.CommonConstants.COMMA))")
    @Mapping(target = "microLoanQuotaList", expression = "java(com.yunxin.core.utils.infra.utils.ConvertUtils.X.toIntegerList(entity.getMicroLoanQuotas(), com.yunxin.core.utils.infra.common.constant.CommonConstants.COMMA))")
    @Mapping(target = "creditCardList", expression = "java(com.yunxin.core.utils.infra.utils.ConvertUtils.X.toIntegerList(entity.getCreditCards(), com.yunxin.core.utils.infra.common.constant.CommonConstants.COMMA))")
    @Mapping(target = "educationLevelList", expression = "java(com.yunxin.core.utils.infra.utils.ConvertUtils.X.toIntegerList(entity.getEducationLevels(), com.yunxin.core.utils.infra.common.constant.CommonConstants.COMMA))")
    @Mapping(target = "houseLevelList", expression = "java(com.yunxin.core.utils.infra.utils.ConvertUtils.X.toIntegerList(entity.getHouseLevels(), com.yunxin.core.utils.infra.common.constant.CommonConstants.COMMA))")
    @Mapping(target = "vehicleLevelList", expression = "java(com.yunxin.core.utils.infra.utils.ConvertUtils.X.toIntegerList(entity.getVehicleLevels(), com.yunxin.core.utils.infra.common.constant.CommonConstants.COMMA))")
    @Mapping(target = "accumulationFundLevelList", expression = "java(com.yunxin.core.utils.infra.utils.ConvertUtils.X.toIntegerList(entity.getAccumulationFundLevels(), com.yunxin.core.utils.infra.common.constant.CommonConstants.COMMA))")
    @Mapping(target = "socialSecurityLevelList", expression = "java(com.yunxin.core.utils.infra.utils.ConvertUtils.X.toIntegerList(entity.getSocialSecurityLevels(), com.yunxin.core.utils.infra.common.constant.CommonConstants.COMMA))")
    @Mapping(target = "insureList", expression = "java(com.yunxin.core.utils.infra.utils.ConvertUtils.X.toIntegerList(entity.getInsures(), com.yunxin.core.utils.infra.common.constant.CommonConstants.COMMA))")
    @Mapping(target = "occupationList", expression = "java(com.yunxin.core.utils.infra.utils.ConvertUtils.X.toIntegerList(entity.getOccupations(), com.yunxin.core.utils.infra.common.constant.CommonConstants.COMMA))")
    @Mapping(target = "occupationIncomeList", expression = "java(com.yunxin.core.utils.infra.utils.ConvertUtils.X.toIntegerList(entity.getOccupationIncomes(), com.yunxin.core.utils.infra.common.constant.CommonConstants.COMMA))")
    ProductCustomConfigDTO toProductCustomConfigDTO(ProductCustomConfigDO entity);

    /**
     * entity 转 dto
     *
     * @param entity entity
     * @return ProductUnitPriceConfigDTO
     */
    ProductUnitPriceConfigDTO toProductUnitPriceConfigDTO(ProductUnitPriceConfigDO entity);


    /**
     * result 转 dto
     *
     * @param result result
     * @return ProductDetailDTO
     */
    @Mapping(target = "equityDescription", expression = "java(com.yunxin.common.utils.JacksonUtils.X.parse(result.getEquityDescription(), new com.fasterxml.jackson.core.type.TypeReference<java.util.List<com.yunxin.core.application.dto.product.ProductDetailDTO.EquityDescription>>() {}))")
    @Mapping(target = "referenceRate", expression = "java(com.yunxin.common.utils.JacksonUtils.X.parse(result.getReferenceRate(), new com.fasterxml.jackson.core.type.TypeReference<com.yunxin.core.application.dto.product.ProductDetailDTO.ReferenceRate>() {}))")
    ProductDetailDTO toProductDetailDTO(ProductDetailResult result);

    /**
     * command 转 entity
     * @param command command
     * @return ProductAdvanceChargeRecord
     */
    @Mapping(target = "advanceChargeDate", expression = "java(com.yunxin.core.utils.infra.utils.DateFormatUtils.X.getDateByStr(command.getAdvanceChargeDate()))")
    ProductAdvanceChargeRecord fromAddProductAdvanceChargeRecordCommand(AddProductAdvanceChargeRecordCommand command);

    /**
     * command 转 entity
     * @param command command
     * @return ProductAdvanceChargeRecord
     */
    @Mapping(target = "advanceChargeDate", expression = "java(com.yunxin.core.utils.infra.utils.DateFormatUtils.X.getDateByStr(command.getAdvanceChargeDate()))")
    ProductAdvanceChargeRecord fromUpdateProductAdvanceChargeRecordCommand(UpdateProductAdvanceChargeRecordCommand command);

    /**
     * command 转 entity
     *
     * @param command command
     * @return ProductInfo
     */
    ProductInfo fromAddProductPromotionInfoCommand(AddProductPromotionInfoCommand command);

    /**
     * command 转 entity
     *
     * @param command command
     * @return ProductPromotionInfo
     */
    @Mapping(target = "equityDescription", expression = "java(com.yunxin.common.utils.JacksonUtils.X.format(command.getEquityDescription()))")
    @Mapping(target = "borrowableAmount", expression = "java(com.yunxin.common.utils.JacksonUtils.X.format(command.getBorrowableAmount()))")
    @Mapping(target = "loanCycle", expression = "java(com.yunxin.common.utils.JacksonUtils.X.format(command.getLoanCycle()))")
    @Mapping(target = "referenceRate", expression = "java(com.yunxin.common.utils.JacksonUtils.X.format(command.getReferenceRate()))")
    @Mapping(target = "commission", expression = "java(com.yunxin.common.utils.JacksonUtils.X.format(command.getCommission()))")
    @Mapping(target = "customerServiceConfig", expression = "java(com.yunxin.common.utils.JacksonUtils.X.format(command.getCustomerServiceConfig()))")
    @Mapping(target = "protocolConfig", expression = "java(com.yunxin.common.utils.JacksonUtils.X.format(command.getProtocolConfig()))")
    ProductPromotionInfo fromAddProductPromotionInfoCommandForPromotionInfo(AddProductPromotionInfoCommand command);

    /**
     * command 转 entity
     *
     * @param command command
     * @return ProductInfo
     */
    @Mapping(target = "id", source = "productId")
    ProductInfo fromUpdateProductPromotionInfoCommand(UpdateProductPromotionInfoCommand command);

    /**
     * command 转 entity
     *
     * @param command command
     * @return ProductPromotionInfo
     */
    @Mapping(target = "equityDescription", expression = "java(com.yunxin.common.utils.JacksonUtils.X.format(command.getEquityDescription()))")
    @Mapping(target = "borrowableAmount", expression = "java(com.yunxin.common.utils.JacksonUtils.X.format(command.getBorrowableAmount()))")
    @Mapping(target = "loanCycle", expression = "java(com.yunxin.common.utils.JacksonUtils.X.format(command.getLoanCycle()))")
    @Mapping(target = "referenceRate", expression = "java(com.yunxin.common.utils.JacksonUtils.X.format(command.getReferenceRate()))")
    @Mapping(target = "commission", expression = "java(com.yunxin.common.utils.JacksonUtils.X.format(command.getCommission()))")
    @Mapping(target = "customerServiceConfig", expression = "java(com.yunxin.common.utils.JacksonUtils.X.format(command.getCustomerServiceConfig()))")
    @Mapping(target = "protocolConfig", expression = "java(com.yunxin.common.utils.JacksonUtils.X.format(command.getProtocolConfig()))")
    ProductPromotionInfo fromUpdateProductPromotionInfoCommandForPromotionInfo(UpdateProductPromotionInfoCommand command);

    /**
     * command 转 entity
     *
     * @param command command
     * @return ProductThrowInConfig
     */
    ProductThrowInConfig fromProductThrowInConfigOperateCommand(ProductThrowInConfigOperateCommand command);

    /**
     * command 转 entity
     *
     * @param command command
     * @return ProductCustomConfig
     */
    @Mapping(target = "beOverdue", expression = "java(com.yunxin.core.utils.infra.utils.ConvertUtils.X.fromList(command.getBeOverdueList(), com.yunxin.core.utils.infra.common.constant.CommonConstants.COMMA))")
    @Mapping(target = "sexes", expression = "java(com.yunxin.core.utils.infra.utils.ConvertUtils.X.fromList(command.getSexList(), com.yunxin.core.utils.infra.common.constant.CommonConstants.COMMA))")
    @Mapping(target = "sesameSeedQuotas", expression = "java(com.yunxin.core.utils.infra.utils.ConvertUtils.X.fromList(command.getSesameSeedQuotaList(), com.yunxin.core.utils.infra.common.constant.CommonConstants.COMMA))")
    @Mapping(target = "antCreditPayQuotas", expression = "java(com.yunxin.core.utils.infra.utils.ConvertUtils.X.fromList(command.getAntCreditPayQuotaList(), com.yunxin.core.utils.infra.common.constant.CommonConstants.COMMA))")
    @Mapping(target = "jdBtQuotas", expression = "java(com.yunxin.core.utils.infra.utils.ConvertUtils.X.fromList(command.getJdBtQuotaList(), com.yunxin.core.utils.infra.common.constant.CommonConstants.COMMA))")
    @Mapping(target = "microLoanQuotas", expression = "java(com.yunxin.core.utils.infra.utils.ConvertUtils.X.fromList(command.getMicroLoanQuotaList(), com.yunxin.core.utils.infra.common.constant.CommonConstants.COMMA))")
    @Mapping(target = "creditCards", expression = "java(com.yunxin.core.utils.infra.utils.ConvertUtils.X.fromList(command.getCreditCardList(), com.yunxin.core.utils.infra.common.constant.CommonConstants.COMMA))")
    @Mapping(target = "educationLevels", expression = "java(com.yunxin.core.utils.infra.utils.ConvertUtils.X.fromList(command.getEducationLevelList(), com.yunxin.core.utils.infra.common.constant.CommonConstants.COMMA))")
    @Mapping(target = "houseLevels", expression = "java(com.yunxin.core.utils.infra.utils.ConvertUtils.X.fromList(command.getHouseLevelList(), com.yunxin.core.utils.infra.common.constant.CommonConstants.COMMA))")
    @Mapping(target = "vehicleLevels", expression = "java(com.yunxin.core.utils.infra.utils.ConvertUtils.X.fromList(command.getVehicleLevelList(), com.yunxin.core.utils.infra.common.constant.CommonConstants.COMMA))")
    @Mapping(target = "accumulationFundLevels", expression = "java(com.yunxin.core.utils.infra.utils.ConvertUtils.X.fromList(command.getAccumulationFundLevelList(), com.yunxin.core.utils.infra.common.constant.CommonConstants.COMMA))")
    @Mapping(target = "socialSecurityLevels", expression = "java(com.yunxin.core.utils.infra.utils.ConvertUtils.X.fromList(command.getSocialSecurityLevelList(), com.yunxin.core.utils.infra.common.constant.CommonConstants.COMMA))")
    @Mapping(target = "insures", expression = "java(com.yunxin.core.utils.infra.utils.ConvertUtils.X.fromList(command.getInsureList(), com.yunxin.core.utils.infra.common.constant.CommonConstants.COMMA))")
    @Mapping(target = "occupations", expression = "java(com.yunxin.core.utils.infra.utils.ConvertUtils.X.fromList(command.getOccupationList(), com.yunxin.core.utils.infra.common.constant.CommonConstants.COMMA))")
    @Mapping(target = "occupationIncomes", expression = "java(com.yunxin.core.utils.infra.utils.ConvertUtils.X.fromList(command.getOccupationIncomeList(), com.yunxin.core.utils.infra.common.constant.CommonConstants.COMMA))")
    ProductCustomConfig fromProductCustomConfigOperateCommand(ProductCustomConfigOperateCommand command);

    /**
     * command 转 entity
     *
     * @param command command
     * @return ProductUnitPriceConfig
     */
    @Mapping(target = "takeEffectTime", expression = "java(com.yunxin.core.utils.infra.utils.DateFormatUtils.X.getDateOrTimeByStr(command.getTakeEffectTime()))")
    ProductUnitPriceConfig fromProductUnitPriceConfigOperateCommand(ProductUnitPriceConfigOperateCommand command);


    /**
     * command 转 condition
     *
     * @param command command
     * @return ProductPageCondition
     */
    ProductPageCondition fromProductPageCommand(ProductPageCommand command);

}
